"use strict";

/*
 * MikoPBX - free phone system for small business
 * Copyright © 2017-2023 Alexey Portnov and Nikolay Beketov
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program.
 * If not, see <https://www.gnu.org/licenses/>.
 */

/* global PbxApi, globalPBXVersion, globalTranslate,
globalWebAdminLanguage, showdown, UserMessage, upgradeStatusLoopWorker, Config */

/**
 * Object for managing PBX firmware updates.
 *
 * @module updatePBX
 */
var updatePBX = {
  /**
   * jQuery object for the form.
   * @type {jQuery}
   */
  $formObj: $('#upgrade-form'),

  /**
   * jQuery object for the submit button.
   * @type {jQuery}
   */
  $submitButton: $('#submitbutton'),

  /**
   * jQuery object for the progress bar.
   * @type {jQuery}
   */
  $progressBar: $('#upload-progress-bar'),

  /**
   * jQuery object for the progress bar label.
   * @type {jQuery}
   */
  $progressBarLabel: $('#upload-progress-bar-label'),

  /**
   * Current version of the PBX firmware.
   * @type {string}
   */
  currentVersion: globalPBXVersion,

  /**
   * jQuery object for the modal form before upgrade.
   * @type {jQuery}
   */
  $upgradeModalForm: $('#update-modal-form'),

  /**
   * jQuery object for the "I have backup" input field.
   * @type {jQuery}
   */
  $iHaveBackupInput: $("input[name='i-have-backup-input']"),

  /**
   * jQuery object for the green button on modal form before upgrade.
   * @type {jQuery}
   */
  $startUpgradeButton: $('#start-upgrade-button'),

  /**
   * There is upgrade process working now flag.
   * @type {boolean}
   */
  upgradeInProgress: false,

  /**
   * Helps to convert markdown into html.
   * @type {Converter}
   */
  converter: new showdown.Converter(),

  /**
   * Initializes the update PBX firmware functionality.
   */
  initialize: function initialize() {
    // Open the upgrade modal form
    updatePBX.$upgradeModalForm.modal(); // Add 'disabled' class to submit button

    updatePBX.$submitButton.addClass('disabled'); // Trigger file input click when clicking on text input or button

    $('input:text, .ui.button', '.ui.action.input').on('click', function (e) {
      $('input:file', $(e.target).parents()).click();
    }); // Update text input value when selecting a file

    $('input:file', '.ui.action.input').on('change', function (e) {
      if (e.target.files[0] !== undefined) {
        var filename = e.target.files[0].name;
        $('input:text', $(e.target).parent()).val(filename);
        updatePBX.$submitButton.removeClass('disabled');
      }
    }); // Track the input field and make submit button available if phrase is equal to 'I have backup'

    updatePBX.$iHaveBackupInput.on('input', function (e) {
      if (updatePBX.$iHaveBackupInput.val() === globalTranslate.upd_EnterIHaveBackupPhrase) {
        updatePBX.$startUpgradeButton.removeClass('disabled');
      } else {
        updatePBX.$startUpgradeButton.addClass('disabled');
      }
    }); // Handle submit button click

    updatePBX.$submitButton.on('click', function (e) {
      e.preventDefault();
      if (updatePBX.$submitButton.hasClass('loading') || updatePBX.upgradeInProgress) return; // Validate the form and show the upgrade modal form on success

      updatePBX.$formObj.form({
        on: 'blur',
        fields: updatePBX.validateRules,
        onSuccess: function onSuccess() {
          updatePBX.$upgradeModalForm.modal({
            closable: false,
            onDeny: function onDeny() {
              return true;
            },
            onApprove: function onApprove() {
              // Start the file upload process
              updatePBX.$submitButton.addClass('loading');
              updatePBX.upgradeInProgress = true;
              var data = $('input:file')[0].files[0];
              PbxApi.FilesUploadFile(data, updatePBX.cbResumableUploadFile);
              return true;
            }
          }).modal('show');
        }
      }); // Validate the form

      updatePBX.$formObj.form('validate form');
    }); // Prepare the request data

    var requestData = {
      PBXVER: globalPBXVersion,
      LANGUAGE: globalWebAdminLanguage
    }; // Send an API request to check for new firmware

    $.api({
      url: "".concat(Config.updateUrl, "checkNewFirmware"),
      on: 'now',
      method: 'POST',
      data: requestData,
      successTest: function successTest(response) {
        // Test whether a JSON response is valid
        return response !== undefined && Object.keys(response).length > 0 && response.result === 'SUCCESS';
      },
      onSuccess: function onSuccess(response) {
        // Iterate through firmware objects and add version information
        var currentVerison = updatePBX.currentVersion.replace('-dev', '');
        response.firmware.forEach(function (obj) {
          var version = obj.version.replace('-dev', '');

          if (versionCompare(version, currentVerison) > 0) {
            updatePBX.addNewVersionInformation(obj);
          }
        }); // Handle redo button click

        $('a.redo').on('click', function (e) {
          e.preventDefault();
          if (updatePBX.$submitButton.hasClass('loading') || updatePBX.upgradeInProgress) return;
          updatePBX.$upgradeModalForm.modal({
            closable: false,
            onDeny: function onDeny() {
              return true;
            },
            onApprove: function onApprove() {
              // Prepare parameters for firmware download
              var params = {};
              var $aLink = $(e.target).closest('a');
              params.updateLink = $aLink.attr('href');
              params.md5 = $aLink.attr('data-md5');
              params.version = $aLink.attr('data-version');
              params.size = $aLink.attr('data-size');
              $aLink.find('i').addClass('loading');
              updatePBX.upgradeInProgress = true;
              PbxApi.FilesDownloadNewFirmware(params, updatePBX.cbAfterStartDownloadFirmware);
              return true;
            }
          }).modal('show');
        });
      }
    });
  },

  /**
   * Callback function for resumable file upload.
   * @param {string} action - The action of the upload.
   * @param {object} params - Additional parameters for the upload.
   */
  cbResumableUploadFile: function cbResumableUploadFile(action, params) {
    switch (action) {
      case 'fileSuccess':
        updatePBX.checkStatusFileMerging(params.response);
        break;

      case 'uploadStart':
        updatePBX.$submitButton.addClass('loading');
        updatePBX.$progressBar.show();
        updatePBX.$progressBarLabel.text(globalTranslate.upd_UploadInProgress);
        break;

      case 'progress':
        updatePBX.$progressBar.progress({
          percent: parseInt(params.percent, 10)
        });
        break;

      case 'error':
        updatePBX.$progressBarLabel.text(globalTranslate.upd_UploadError);
        updatePBX.$submitButton.removeClass('loading');
        UserMessage.showMultiString(globalTranslate.upd_UploadError);
        break;

      default:
    }
  },

  /**
   * Checks the status of the file merging process.
   * @param {string} response - The response from the /pbxcore/api/upload/status function.
   */
  checkStatusFileMerging: function checkStatusFileMerging(response) {
    if (response === undefined || PbxApi.tryParseJSON(response) === false) {
      UserMessage.showMultiString("".concat(globalTranslate.upd_UploadError));
      return;
    }

    var json = JSON.parse(response);

    if (json === undefined || json.data === undefined) {
      UserMessage.showMultiString("".concat(globalTranslate.upd_UploadError));
      return;
    }

    var fileID = json.data.upload_id;
    var filePath = json.data.filename; // Wait until system glued all parts of file

    mergingCheckWorker.initialize(fileID, filePath);
  },

  /**
   * Callback after start PBX upgrading
   * @param response
   */
  cbAfterStartUpdate: function cbAfterStartUpdate(response) {
    if (response.result !== undefined && response.result === false) {
      UserMessage.showMultiString(response.messages, globalTranslate.upd_UpgradeError);
      updatePBX.$submitButton.removeClass('loading');
    }
  },

  /**
   * After start online upgrade we have to wait an answer,
   * and then start status check worker
   */
  cbAfterStartDownloadFirmware: function cbAfterStartDownloadFirmware(response) {
    if (response.filename !== undefined) {
      upgradeStatusLoopWorker.initialize(response.filename);
    } else {
      updatePBX.upgradeInProgress = false;
      $('i.loading.redo').removeClass('loading');
    }
  },

  /**
   * Add new block of update information on page
   */
  addNewVersionInformation: function addNewVersionInformation(obj) {
    $('#online-updates-block').show();
    var markdownText = decodeURIComponent(obj.description);
    markdownText = markdownText.replace(/<br>/g, '\r');
    markdownText = markdownText.replace(/<br >/g, '\r');
    markdownText = markdownText.replace(/\* \*/g, '*');
    markdownText = markdownText.replace(/\*\*/g, '*');
    var html = updatePBX.converter.makeHtml(markdownText);
    var dymanicRow = "\n\t\t\t<tr class=\"update-row\">\n\t\t\t<td class=\"center aligned\">".concat(obj.version, "</td>\n\t\t\t<td>").concat(html, "</td>\n\t\t\t<td class=\"right aligned collapsing\">\n    \t\t<div class=\"ui small basic icon buttons action-buttons\">\n    \t\t\t<a href=\"").concat(obj.href, "\" class=\"ui button redo popuped\" \n    \t\t\t\tdata-content = \"").concat(globalTranslate.bt_ToolTipUpgradeOnline, "\"\n\t\t\t\t\tdata-md5 =\"").concat(obj.md5, "\" data-size =\"").concat(obj.size, "\"\n\t\t\t\t\tdata-version = \"").concat(obj.version, "\" >\n\t\t\t\t\t<i class=\"icon redo blue\"></i>\n\t\t\t\t\t<span class=\"percent\"></span>\n\t\t\t\t</a>\n\t\t\t\t<a href=\"").concat(obj.href, "\" class=\"ui button download popuped\" \n\t\t\t\t\tdata-content = \"").concat(globalTranslate.bt_ToolTipDownload, "\"\n\t\t\t\t\tdata-md5 =\"").concat(obj.md5, "\" data-size =\"").concat(obj.size, "\">\n\t\t\t\t\t<i class=\"icon download blue\"></i>\n\t\t\t\t</a>\n    \t\t</div>   \n\t</tr>");
    $('#updates-table tbody').append(dymanicRow);
    $('a.popuped').popup();
  }
}; // When the document is ready, initialize the update pbx firmware from image page

$(document).ready(function () {
  updatePBX.initialize();
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9VcGRhdGUvdXBkYXRlLWluZGV4LmpzIl0sIm5hbWVzIjpbInVwZGF0ZVBCWCIsIiRmb3JtT2JqIiwiJCIsIiRzdWJtaXRCdXR0b24iLCIkcHJvZ3Jlc3NCYXIiLCIkcHJvZ3Jlc3NCYXJMYWJlbCIsImN1cnJlbnRWZXJzaW9uIiwiZ2xvYmFsUEJYVmVyc2lvbiIsIiR1cGdyYWRlTW9kYWxGb3JtIiwiJGlIYXZlQmFja3VwSW5wdXQiLCIkc3RhcnRVcGdyYWRlQnV0dG9uIiwidXBncmFkZUluUHJvZ3Jlc3MiLCJjb252ZXJ0ZXIiLCJzaG93ZG93biIsIkNvbnZlcnRlciIsImluaXRpYWxpemUiLCJtb2RhbCIsImFkZENsYXNzIiwib24iLCJlIiwidGFyZ2V0IiwicGFyZW50cyIsImNsaWNrIiwiZmlsZXMiLCJ1bmRlZmluZWQiLCJmaWxlbmFtZSIsIm5hbWUiLCJwYXJlbnQiLCJ2YWwiLCJyZW1vdmVDbGFzcyIsImdsb2JhbFRyYW5zbGF0ZSIsInVwZF9FbnRlcklIYXZlQmFja3VwUGhyYXNlIiwicHJldmVudERlZmF1bHQiLCJoYXNDbGFzcyIsImZvcm0iLCJmaWVsZHMiLCJ2YWxpZGF0ZVJ1bGVzIiwib25TdWNjZXNzIiwiY2xvc2FibGUiLCJvbkRlbnkiLCJvbkFwcHJvdmUiLCJkYXRhIiwiUGJ4QXBpIiwiRmlsZXNVcGxvYWRGaWxlIiwiY2JSZXN1bWFibGVVcGxvYWRGaWxlIiwicmVxdWVzdERhdGEiLCJQQlhWRVIiLCJMQU5HVUFHRSIsImdsb2JhbFdlYkFkbWluTGFuZ3VhZ2UiLCJhcGkiLCJ1cmwiLCJDb25maWciLCJ1cGRhdGVVcmwiLCJtZXRob2QiLCJzdWNjZXNzVGVzdCIsInJlc3BvbnNlIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsInJlc3VsdCIsImN1cnJlbnRWZXJpc29uIiwicmVwbGFjZSIsImZpcm13YXJlIiwiZm9yRWFjaCIsIm9iaiIsInZlcnNpb24iLCJ2ZXJzaW9uQ29tcGFyZSIsImFkZE5ld1ZlcnNpb25JbmZvcm1hdGlvbiIsInBhcmFtcyIsIiRhTGluayIsImNsb3Nlc3QiLCJ1cGRhdGVMaW5rIiwiYXR0ciIsIm1kNSIsInNpemUiLCJmaW5kIiwiRmlsZXNEb3dubG9hZE5ld0Zpcm13YXJlIiwiY2JBZnRlclN0YXJ0RG93bmxvYWRGaXJtd2FyZSIsImFjdGlvbiIsImNoZWNrU3RhdHVzRmlsZU1lcmdpbmciLCJzaG93IiwidGV4dCIsInVwZF9VcGxvYWRJblByb2dyZXNzIiwicHJvZ3Jlc3MiLCJwZXJjZW50IiwicGFyc2VJbnQiLCJ1cGRfVXBsb2FkRXJyb3IiLCJVc2VyTWVzc2FnZSIsInNob3dNdWx0aVN0cmluZyIsInRyeVBhcnNlSlNPTiIsImpzb24iLCJKU09OIiwicGFyc2UiLCJmaWxlSUQiLCJ1cGxvYWRfaWQiLCJmaWxlUGF0aCIsIm1lcmdpbmdDaGVja1dvcmtlciIsImNiQWZ0ZXJTdGFydFVwZGF0ZSIsIm1lc3NhZ2VzIiwidXBkX1VwZ3JhZGVFcnJvciIsInVwZ3JhZGVTdGF0dXNMb29wV29ya2VyIiwibWFya2Rvd25UZXh0IiwiZGVjb2RlVVJJQ29tcG9uZW50IiwiZGVzY3JpcHRpb24iLCJodG1sIiwibWFrZUh0bWwiLCJkeW1hbmljUm93IiwiaHJlZiIsImJ0X1Rvb2xUaXBVcGdyYWRlT25saW5lIiwiYnRfVG9vbFRpcERvd25sb2FkIiwiYXBwZW5kIiwicG9wdXAiLCJkb2N1bWVudCIsInJlYWR5Il0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBTUEsU0FBUyxHQUFHO0FBQ2Q7QUFDSjtBQUNBO0FBQ0E7QUFDSUMsRUFBQUEsUUFBUSxFQUFFQyxDQUFDLENBQUMsZUFBRCxDQUxHOztBQU9kO0FBQ0o7QUFDQTtBQUNBO0FBQ0lDLEVBQUFBLGFBQWEsRUFBRUQsQ0FBQyxD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LFVBQWpDO0FBQ0F4RyxJQUFBQSxDQUFDLENBQUMsV0FBRCxDQUFELENBQWU2RyxLQUFmO0FBQ0g7QUFqU2EsQ0FBbEIsQyxDQW9TQTs7QUFDQTdHLENBQUMsQ0FBQzhHLFFBQUQsQ0FBRCxDQUFZQyxLQUFaLENBQWtCLFlBQU07QUFDcEJqSCxFQUFBQSxTQUFTLENBQUNlLFVBQVY7QUFDSCxDQUZEIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIE1pa29QQlggLSBmcmVlIHBob25lIHN5c3RlbSBmb3Igc21hbGwgYnVzaW5lc3NcbiAqIENvcHlyaWdodCDCqSAyMDE3LTIwMjMgQWxleGV5IFBvcnRub3YgYW5kIE5pa29sYXkgQmVrZXRvdlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS5cbiAqIElmIG5vdCwgc2VlIDxodHRwczovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKi9cblxuLyogZ2xvYmFsIFBieEFwaSwgZ2xvYmFsUEJYVmVyc2lvbiwgZ2xvYmFsVHJhbnNsYXRlLFxuZ2xvYmFsV2ViQWRtaW5MYW5ndWFnZSwgc2hvd2Rvd24sIFVzZXJNZXNzYWdlLCB1cGdyYWRlU3RhdHVzTG9vcFdvcmtlciwgQ29uZmlnICovXG5cbi8qKlxuICogT2JqZWN0IGZvciBtYW5hZ2luZyBQQlggZmlybXdhcmUgdXBkYXRlcy5cbiAqXG4gKiBAbW9kdWxlIHVwZGF0ZVBCWFxuICovXG5jb25zdCB1cGRhdGVQQlggPSB7XG4gICAgLyoqXG4gICAgICogalF1ZXJ5IG9iamVjdCBmb3IgdGhlIGZvcm0uXG4gICAgICogQHR5cGUge2pRdWVyeX1cbiAgICAgKi9cbiAgICAkZm9ybU9iajogJCgnI3VwZ3JhZGUtZm9ybScpLFxuXG4gICAgLyoqXG4gICAgICogalF1ZXJ5IG9iamVjdCBmb3IgdGhlIHN1Ym1pdCBidXR0b24uXG4gICAgICogQHR5cGUge2pRdWVyeX1cbiAgICAgKi9cbiAgICAkc3VibWl0QnV0dG9uOiAkKCcjc3VibWl0YnV0dG9uJyksXG5cbiAgICAvKipcbiAgICAgKiBqUXVlcnkgb2JqZWN0IGZvciB0aGUgcHJvZ3Jlc3MgYmFyLlxuICAgICAqIEB0eXBlIHtqUXVlcnl9XG4gICAgICovXG4gICAgJHByb2dyZXNzQmFyOiAkKCcjdXBsb2FkLXByb2dyZXNzLWJhcicpLFxuXG4gICAgLyoqXG4gICAgICogalF1ZXJ5IG9iamVjdCBmb3IgdGhlIHByb2dyZXNzIGJhciBsYWJlbC5cbiAgICAgKiBAdHlwZSB7alF1ZXJ5fVxuICAgICAqL1xuICAgICRwcm9ncmVzc0JhckxhYmVsOiAkKCcjdXBsb2FkLXByb2dyZXNzLWJhci1sYWJlbCcpLFxuXG4gICAgLyoqXG4gICAgICogQ3VycmVudCB2ZXJzaW9uIG9mIHRoZSBQQlggZmlybXdhcmUuXG4gICAgICogQHR5cGUge3N0cmluZ31cbiAgICAgKi9cbiAgICBjdXJyZW50VmVyc2lvbjogZ2xvYmFsUEJYVmVyc2lvbixcblxuICAgIC8qKlxuICAgICAqIGpRdWVyeSBvYmplY3QgZm9yIHRoZSBtb2RhbCBmb3JtIGJlZm9yZSB1cGdyYWRlLlxuICAgICAqIEB0eXBlIHtqUXVlcnl9XG4gICAgICovXG4gICAgJHVwZ3JhZGVNb2RhbEZvcm06ICQoJyN1cGRhdGUtbW9kYWwtZm9ybScpLFxuXG4gICAgLyoqXG4gICAgICogalF1ZXJ5IG9iamVjdCBmb3IgdGhlIFwiSSBoYXZlIGJhY2t1cFwiIGlucHV0IGZpZWxkLlxuICAgICAqIEB0eXBlIHtqUXVlcnl9XG4gICAgICovXG4gICAgJGlIYXZlQmFja3VwSW5wdXQ6ICQoXCJpbnB1dFtuYW1lPSdpLWhhdmUtYmFja3VwLWlucHV0J11cIiksXG5cbiAgICAvKipcbiAgICAgKiBqUXVlcnkgb2JqZWN0IGZvciB0aGUgZ3JlZW4gYnV0dG9uIG9uIG1vZGFsIGZvcm0gYmVmb3JlIHVwZ3JhZGUuXG4gICAgICogQHR5cGUge2pRdWVyeX1cbiAgICAgKi9cbiAgICAkc3RhcnRVcGdyYWRlQnV0dG9uOiAkKCcjc3RhcnQtdXBncmFkZS1idXR0b24nKSxcblxuICAgIC8qKlxuICAgICAqIFRoZXJlIGlzIHVwZ3JhZGUgcHJvY2VzcyB3b3JraW5nIG5vdyBmbGFnLlxuICAgICAqIEB0eXBlIHtib29sZWFufVxuICAgICAqL1xuICAgIHVwZ3JhZGVJblByb2dyZXNzOiBmYWxzZSxcblxuICAgIC8qKlxuICAgICAqIEhlbHBzIHRvIGNvbnZlcnQgbWFya2Rvd24gaW50byBodG1sLlxuICAgICAqIEB0eXBlIHtDb252ZXJ0ZXJ9XG4gICAgICovXG4gICAgY29udmVydGVyOiBuZXcgc2hvd2Rvd24uQ29udmVydGVyKCksXG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplcyB0aGUgdXBkYXRlIFBCWCBmaXJtd2FyZSBmdW5jdGlvbmFsaXR5LlxuICAgICAqL1xuICAgIGluaXRpYWxpemUoKSB7XG5cbiAgICAgICAgLy8gT3BlbiB0aGUgdXBncmFkZSBtb2RhbCBmb3JtXG4gICAgICAgIHVwZGF0ZVBCWC4kdXBncmFkZU1vZGFsRm9ybS5tb2RhbCgpO1xuXG4gICAgICAgIC8vIEFkZCAnZGlzYWJsZWQnIGNsYXNzIHRvIHN1Ym1pdCBidXR0b25cbiAgICAgICAgdXBkYXRlUEJYLiRzdWJtaXRCdXR0b24uYWRkQ2xhc3MoJ2Rpc2FibGVkJyk7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBmaWxlIGlucHV0IGNsaWNrIHdoZW4gY2xpY2tpbmcgb24gdGV4dCBpbnB1dCBvciBidXR0b25cbiAgICAgICAgJCgnaW5wdXQ6dGV4dCwgLnVpLmJ1dHRvbicsICcudWkuYWN0aW9uLmlucHV0Jykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgICQoJ2lucHV0OmZpbGUnLCAkKGUudGFyZ2V0KS5wYXJlbnRzKCkpLmNsaWNrKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFVwZGF0ZSB0ZXh0IGlucHV0IHZhbHVlIHdoZW4gc2VsZWN0aW5nIGEgZmlsZVxuICAgICAgICAkKCdpbnB1dDpmaWxlJywgJy51aS5hY3Rpb24uaW5wdXQnKS5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGlmIChlLnRhcmdldC5maWxlc1swXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmlsZW5hbWUgPSBlLnRhcmdldC5maWxlc1swXS5uYW1lO1xuICAgICAgICAgICAgICAgICQoJ2lucHV0OnRleHQnLCAkKGUudGFyZ2V0KS5wYXJlbnQoKSkudmFsKGZpbGVuYW1lKTtcbiAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHN1Ym1pdEJ1dHRvbi5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVHJhY2sgdGhlIGlucHV0IGZpZWxkIGFuZCBtYWtlIHN1Ym1pdCBidXR0b24gYXZhaWxhYmxlIGlmIHBocmFzZSBpcyBlcXVhbCB0byAnSSBoYXZlIGJhY2t1cCdcbiAgICAgICAgdXBkYXRlUEJYLiRpSGF2ZUJhY2t1cElucHV0Lm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHVwZGF0ZVBCWC4kaUhhdmVCYWNrdXBJbnB1dC52YWwoKT09PWdsb2JhbFRyYW5zbGF0ZS51cGRfRW50ZXJJSGF2ZUJhY2t1cFBocmFzZSkge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHN0YXJ0VXBncmFkZUJ1dHRvbi5yZW1vdmVDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHN0YXJ0VXBncmFkZUJ1dHRvbi5hZGRDbGFzcygnZGlzYWJsZWQnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBzdWJtaXQgYnV0dG9uIGNsaWNrXG4gICAgICAgIHVwZGF0ZVBCWC4kc3VibWl0QnV0dG9uLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBpZiAodXBkYXRlUEJYLiRzdWJtaXRCdXR0b24uaGFzQ2xhc3MoJ2xvYWRpbmcnKSB8fCB1cGRhdGVQQlgudXBncmFkZUluUHJvZ3Jlc3MpIHJldHVybjtcblxuICAgICAgICAgICAgLy8gVmFsaWRhdGUgdGhlIGZvcm0gYW5kIHNob3cgdGhlIHVwZ3JhZGUgbW9kYWwgZm9ybSBvbiBzdWNjZXNzXG4gICAgICAgICAgICB1cGRhdGVQQlguJGZvcm1PYmpcbiAgICAgICAgICAgICAgICAuZm9ybSh7XG4gICAgICAgICAgICAgICAgICAgIG9uOiAnYmx1cicsXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkczogdXBkYXRlUEJYLnZhbGlkYXRlUnVsZXMsXG4gICAgICAgICAgICAgICAgICAgIG9uU3VjY2VzcygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZVBCWC4kdXBncmFkZU1vZGFsRm9ybVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tb2RhbCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25EZW55OiAoKSA9PiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkFwcHJvdmU6ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IHRoZSBmaWxlIHVwbG9hZCBwcm9jZXNzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHN1Ym1pdEJ1dHRvbi5hZGRDbGFzcygnbG9hZGluZycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlUEJYLnVwZ3JhZGVJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSAkKCdpbnB1dDpmaWxlJylbMF0uZmlsZXNbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYnhBcGkuRmlsZXNVcGxvYWRGaWxlKGRhdGEsIHVwZGF0ZVBCWC5jYlJlc3VtYWJsZVVwbG9hZEZpbGUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAubW9kYWwoJ3Nob3cnKTtcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gVmFsaWRhdGUgdGhlIGZvcm1cbiAgICAgICAgICAgIHVwZGF0ZVBCWC4kZm9ybU9iai5mb3JtKCd2YWxpZGF0ZSBmb3JtJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFByZXBhcmUgdGhlIHJlcXVlc3QgZGF0YVxuICAgICAgICBjb25zdCByZXF1ZXN0RGF0YSA9IHtcbiAgICAgICAgICAgIFBCWFZFUjogZ2xvYmFsUEJYVmVyc2lvbixcbiAgICAgICAgICAgIExBTkdVQUdFOiBnbG9iYWxXZWJBZG1pbkxhbmd1YWdlLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFNlbmQgYW4gQVBJIHJlcXVlc3QgdG8gY2hlY2sgZm9yIG5ldyBmaXJtd2FyZVxuICAgICAgICAkLmFwaSh7XG4gICAgICAgICAgICB1cmw6IGAke0NvbmZpZy51cGRhdGVVcmx9Y2hlY2tOZXdGaXJtd2FyZWAsXG4gICAgICAgICAgICBvbjogJ25vdycsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHJlcXVlc3REYXRhLFxuICAgICAgICAgICAgc3VjY2Vzc1Rlc3QocmVzcG9uc2UpIHtcbiAgICAgICAgICAgICAgICAvLyBUZXN0IHdoZXRoZXIgYSBKU09OIHJlc3BvbnNlIGlzIHZhbGlkXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICAgICAgJiYgT2JqZWN0LmtleXMocmVzcG9uc2UpLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgJiYgcmVzcG9uc2UucmVzdWx0ID09PSAnU1VDQ0VTUyc7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgb25TdWNjZXNzKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aHJvdWdoIGZpcm13YXJlIG9iamVjdHMgYW5kIGFkZCB2ZXJzaW9uIGluZm9ybWF0aW9uXG4gICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFZlcmlzb24gPSB1cGRhdGVQQlguY3VycmVudFZlcnNpb24ucmVwbGFjZSgnLWRldicsICcnKTtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5maXJtd2FyZS5mb3JFYWNoKChvYmopID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmVyc2lvbiA9IG9iai52ZXJzaW9uLnJlcGxhY2UoJy1kZXYnLCAnJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh2ZXJzaW9uQ29tcGFyZSh2ZXJzaW9uLCBjdXJyZW50VmVyaXNvbikgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVQQlguYWRkTmV3VmVyc2lvbkluZm9ybWF0aW9uKG9iaik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSByZWRvIGJ1dHRvbiBjbGlja1xuICAgICAgICAgICAgICAgICQoJ2EucmVkbycpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVwZGF0ZVBCWC4kc3VibWl0QnV0dG9uLmhhc0NsYXNzKCdsb2FkaW5nJykgfHwgdXBkYXRlUEJYLnVwZ3JhZGVJblByb2dyZXNzKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZVBCWC4kdXBncmFkZU1vZGFsRm9ybVxuICAgICAgICAgICAgICAgICAgICAgICAgLm1vZGFsKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zYWJsZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25EZW55OiAoKSA9PiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQXBwcm92ZTogKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQcmVwYXJlIHBhcmFtZXRlcnMgZm9yIGZpcm13YXJlIGRvd25sb2FkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCAkYUxpbmsgPSAkKGUudGFyZ2V0KS5jbG9zZXN0KCdhJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy51cGRhdGVMaW5rID0gJGFMaW5rLmF0dHIoJ2hyZWYnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLm1kNSA9ICRhTGluay5hdHRyKCdkYXRhLW1kNScpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXMudmVyc2lvbiA9ICRhTGluay5hdHRyKCdkYXRhLXZlcnNpb24nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLnNpemUgPSAkYUxpbmsuYXR0cignZGF0YS1zaXplJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRhTGluay5maW5kKCdpJykuYWRkQ2xhc3MoJ2xvYWRpbmcnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlUEJYLnVwZ3JhZGVJblByb2dyZXNzID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGJ4QXBpLkZpbGVzRG93bmxvYWROZXdGaXJtd2FyZShwYXJhbXMsIHVwZGF0ZVBCWC5jYkFmdGVyU3RhcnREb3dubG9hZEZpcm13YXJlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAubW9kYWwoJ3Nob3cnKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgcmVzdW1hYmxlIGZpbGUgdXBsb2FkLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24gLSBUaGUgYWN0aW9uIG9mIHRoZSB1cGxvYWQuXG4gICAgICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIEFkZGl0aW9uYWwgcGFyYW1ldGVycyBmb3IgdGhlIHVwbG9hZC5cbiAgICAgKi9cbiAgICBjYlJlc3VtYWJsZVVwbG9hZEZpbGUoYWN0aW9uLCBwYXJhbXMpIHtcbiAgICAgICAgc3dpdGNoIChhY3Rpb24pIHtcbiAgICAgICAgICAgIGNhc2UgJ2ZpbGVTdWNjZXNzJzpcbiAgICAgICAgICAgICAgICB1cGRhdGVQQlguY2hlY2tTdGF0dXNGaWxlTWVyZ2luZyhwYXJhbXMucmVzcG9uc2UpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndXBsb2FkU3RhcnQnOlxuICAgICAgICAgICAgICAgIHVwZGF0ZVBCWC4kc3VibWl0QnV0dG9uLmFkZENsYXNzKCdsb2FkaW5nJyk7XG4gICAgICAgICAgICAgICAgdXBkYXRlUEJYLiRwcm9ncmVzc0Jhci5zaG93KCk7XG4gICAgICAgICAgICAgICAgdXBkYXRlUEJYLiRwcm9ncmVzc0JhckxhYmVsLnRleHQoZ2xvYmFsVHJhbnNsYXRlLnVwZF9VcGxvYWRJblByb2dyZXNzKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3Byb2dyZXNzJzpcbiAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHByb2dyZXNzQmFyLnByb2dyZXNzKHtcbiAgICAgICAgICAgICAgICAgICAgcGVyY2VudDogcGFyc2VJbnQocGFyYW1zLnBlcmNlbnQsIDEwKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHByb2dyZXNzQmFyTGFiZWwudGV4dChnbG9iYWxUcmFuc2xhdGUudXBkX1VwbG9hZEVycm9yKTtcbiAgICAgICAgICAgICAgICB1cGRhdGVQQlguJHN1Ym1pdEJ1dHRvbi5yZW1vdmVDbGFzcygnbG9hZGluZycpO1xuICAgICAgICAgICAgICAgIFVzZXJNZXNzYWdlLnNob3dNdWx0aVN0cmluZyhnbG9iYWxUcmFuc2xhdGUudXBkX1VwbG9hZEVycm9yKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQ2hlY2tzIHRoZSBzdGF0dXMgb2YgdGhlIGZpbGUgbWVyZ2luZyBwcm9jZXNzLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSByZXNwb25zZSAtIFRoZSByZXNwb25zZSBmcm9tIHRoZSAvcGJ4Y29yZS9hcGkvdXBsb2FkL3N0YXR1cyBmdW5jdGlvbi5cbiAgICAgKi9cbiAgICBjaGVja1N0YXR1c0ZpbGVNZXJnaW5nKHJlc3BvbnNlKSB7XG4gICAgICAgIGlmIChyZXNwb25zZSA9PT0gdW5kZWZpbmVkIHx8IFBieEFwaS50cnlQYXJzZUpTT04ocmVzcG9uc2UpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgVXNlck1lc3NhZ2Uuc2hvd011bHRpU3RyaW5nKGAke2dsb2JhbFRyYW5zbGF0ZS51cGRfVXBsb2FkRXJyb3J9YCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QganNvbiA9IEpTT04ucGFyc2UocmVzcG9uc2UpO1xuICAgICAgICBpZiAoanNvbiA9PT0gdW5kZWZpbmVkIHx8IGpzb24uZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBVc2VyTWVzc2FnZS5zaG93TXVsdGlTdHJpbmcoYCR7Z2xvYmFsVHJhbnNsYXRlLnVwZF9VcGxvYWRFcnJvcn1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmaWxlSUQgPSBqc29uLmRhdGEudXBsb2FkX2lkO1xuICAgICAgICBjb25zdCBmaWxlUGF0aCA9IGpzb24uZGF0YS5maWxlbmFtZTtcbiAgICAgICAgLy8gV2FpdCB1bnRpbCBzeXN0ZW0gZ2x1ZWQgYWxsIHBhcnRzIG9mIGZpbGVcbiAgICAgICAgbWVyZ2luZ0NoZWNrV29ya2VyLmluaXRpYWxpemUoZmlsZUlELCBmaWxlUGF0aCk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIGFmdGVyIHN0YXJ0IFBCWCB1cGdyYWRpbmdcbiAgICAgKiBAcGFyYW0gcmVzcG9uc2VcbiAgICAgKi9cbiAgICBjYkFmdGVyU3RhcnRVcGRhdGUocmVzcG9uc2UpIHtcbiAgICAgICAgaWYgKHJlc3BvbnNlLnJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIHJlc3BvbnNlLnJlc3VsdD09PWZhbHNlKSB7XG4gICAgICAgICAgICBVc2VyTWVzc2FnZS5zaG93TXVsdGlTdHJpbmcocmVzcG9uc2UubWVzc2FnZXMsIGdsb2JhbFRyYW5zbGF0ZS51cGRfVXBncmFkZUVycm9yKTtcbiAgICAgICAgICAgIHVwZGF0ZVBCWC4kc3VibWl0QnV0dG9uLnJlbW92ZUNsYXNzKCdsb2FkaW5nJyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogQWZ0ZXIgc3RhcnQgb25saW5lIHVwZ3JhZGUgd2UgaGF2ZSB0byB3YWl0IGFuIGFuc3dlcixcbiAgICAgKiBhbmQgdGhlbiBzdGFydCBzdGF0dXMgY2hlY2sgd29ya2VyXG4gICAgICovXG4gICAgY2JBZnRlclN0YXJ0RG93bmxvYWRGaXJtd2FyZShyZXNwb25zZSkge1xuICAgICAgICBpZiAocmVzcG9uc2UuZmlsZW5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdXBncmFkZVN0YXR1c0xvb3BXb3JrZXIuaW5pdGlhbGl6ZShyZXNwb25zZS5maWxlbmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB1cGRhdGVQQlgudXBncmFkZUluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICAgICAgICAgICQoJ2kubG9hZGluZy5yZWRvJykucmVtb3ZlQ2xhc3MoJ2xvYWRpbmcnKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBBZGQgbmV3IGJsb2NrIG9mIHVwZGF0ZSBpbmZvcm1hdGlvbiBvbiBwYWdlXG4gICAgICovXG4gICAgYWRkTmV3VmVyc2lvbkluZm9ybWF0aW9uKG9iaikge1xuICAgICAgICAkKCcjb25saW5lLXVwZGF0ZXMtYmxvY2snKS5zaG93KCk7XG4gICAgICAgIGxldCBtYXJrZG93blRleHQgPSBkZWNvZGVVUklDb21wb25lbnQob2JqLmRlc2NyaXB0aW9uKTtcbiAgICAgICAgbWFya2Rvd25UZXh0ID0gbWFya2Rvd25UZXh0LnJlcGxhY2UoLzxicj4vZywgJ1xccicpO1xuICAgICAgICBtYXJrZG93blRleHQgPSBtYXJrZG93blRleHQucmVwbGFjZSgvPGJyID4vZywgJ1xccicpO1xuICAgICAgICBtYXJrZG93blRleHQgPSBtYXJrZG93blRleHQucmVwbGFjZSgvXFwqIFxcKi9nLCAnKicpO1xuICAgICAgICBtYXJrZG93blRleHQgPSBtYXJrZG93blRleHQucmVwbGFjZSgvXFwqXFwqL2csICcqJyk7XG4gICAgICAgIGNvbnN0IGh0bWwgPSB1cGRhdGVQQlguY29udmVydGVyLm1ha2VIdG1sKG1hcmtkb3duVGV4dCk7XG4gICAgICAgIGNvbnN0IGR5bWFuaWNSb3cgPSBgXG5cdFx0XHQ8dHIgY2xhc3M9XCJ1cGRhdGUtcm93XCI+XG5cdFx0XHQ8dGQgY2xhc3M9XCJjZW50ZXIgYWxpZ25lZFwiPiR7b2JqLnZlcnNpb259PC90ZD5cblx0XHRcdDx0ZD4ke2h0bWx9PC90ZD5cblx0XHRcdDx0ZCBjbGFzcz1cInJpZ2h0IGFsaWduZWQgY29sbGFwc2luZ1wiPlxuICAgIFx0XHQ8ZGl2IGNsYXNzPVwidWkgc21hbGwgYmFzaWMgaWNvbiBidXR0b25zIGFjdGlvbi1idXR0b25zXCI+XG4gICAgXHRcdFx0PGEgaHJlZj1cIiR7b2JqLmhyZWZ9XCIgY2xhc3M9XCJ1aSBidXR0b24gcmVkbyBwb3B1cGVkXCIgXG4gICAgXHRcdFx0XHRkYXRhLWNvbnRlbnQgPSBcIiR7Z2xvYmFsVHJhbnNsYXRlLmJ0X1Rvb2xUaXBVcGdyYWRlT25saW5lfVwiXG5cdFx0XHRcdFx0ZGF0YS1tZDUgPVwiJHtvYmoubWQ1fVwiIGRhdGEtc2l6ZSA9XCIke29iai5zaXplfVwiXG5cdFx0XHRcdFx0ZGF0YS12ZXJzaW9uID0gXCIke29iai52ZXJzaW9ufVwiID5cblx0XHRcdFx0XHQ8aSBjbGFzcz1cImljb24gcmVkbyBibHVlXCI+PC9pPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzPVwicGVyY2VudFwiPjwvc3Bhbj5cblx0XHRcdFx0PC9hPlxuXHRcdFx0XHQ8YSBocmVmPVwiJHtvYmouaHJlZn1cIiBjbGFzcz1cInVpIGJ1dHRvbiBkb3dubG9hZCBwb3B1cGVkXCIgXG5cdFx0XHRcdFx0ZGF0YS1jb250ZW50ID0gXCIke2dsb2JhbFRyYW5zbGF0ZS5idF9Ub29sVGlwRG93bmxvYWR9XCJcblx0XHRcdFx0XHRkYXRhLW1kNSA9XCIke29iai5tZDV9XCIgZGF0YS1zaXplID1cIiR7b2JqLnNpemV9XCI+XG5cdFx0XHRcdFx0PGkgY2xhc3M9XCJpY29uIGRvd25sb2FkIGJsdWVcIj48L2k+XG5cdFx0XHRcdDwvYT5cbiAgICBcdFx0PC9kaXY+ICAgXG5cdDwvdHI+YDtcbiAgICAgICAgJCgnI3VwZGF0ZXMtdGFibGUgdGJvZHknKS5hcHBlbmQoZHltYW5pY1Jvdyk7XG4gICAgICAgICQoJ2EucG9wdXBlZCcpLnBvcHVwKCk7XG4gICAgfSxcbn07XG5cbi8vIFdoZW4gdGhlIGRvY3VtZW50IGlzIHJlYWR5LCBpbml0aWFsaXplIHRoZSB1cGRhdGUgcGJ4IGZpcm13YXJlIGZyb20gaW1hZ2UgcGFnZVxuJChkb2N1bWVudCkucmVhZHkoKCkgPT4ge1xuICAgIHVwZGF0ZVBCWC5pbml0aWFsaXplKCk7XG59KTtcblxuIl19